package com.example.stock.business;

import com.example.stock.controller.dto.DailyDetailDTO;
import com.example.stock.controller.dto.StockOperateDTO;
import com.example.stock.excel.StockOperate;
import com.example.stock.model.DailyDetail;
import com.example.stock.model.MonthDetail;
import com.example.stock.service.DailyDataService;
import com.example.stock.service.MonthDataService;
import com.example.stock.service.StockOperationService;
import com.example.stock.util.DateUtil;
import com.example.stock.util.NumberUtil;
import com.example.stock.util.OperationConstant;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

@Component
public class LastedOperationBusiness {

    @Autowired
    StockOperationService stockOperationService;

    @Autowired
    DailyDataService dailyDataService;

    @Autowired
    MonthDataService monthDataService;

    @Cacheable(value = "getLastedOperation", key = "#stock")
    public List<StockOperateDTO> getLastedOperation(String stock) {

        List<StockOperateDTO> ret = new ArrayList<>();

        // 需要进行价格监控的操作类型
        List<String> monitorOps = List.of(new String[]{OperationConstant.BUY, OperationConstant.SELL, OperationConstant.MOCK_BUY, OperationConstant.MOCK_SELL});

        List<StockOperate> lastedOperationData;
        if (stock.equals("ALL")) {
            lastedOperationData = stockOperationService.getLastedOperationData(750);
        } else {
            lastedOperationData = stockOperationService.getStockOperationData(stock);
        }

        lastedOperationData.forEach(i -> {
            StockOperateDTO stockOperateDTO = new StockOperateDTO();
            BeanUtils.copyProperties(i, stockOperateDTO);

            String operation = i.getOperation();
            String stockName = i.getStock();
            String date = DateUtil.dateDailyFormat(i.getDate());

            ret.add(stockOperateDTO);
            if (!monitorOps.contains(operation)) {
                return;
            }

            stockOperateDTO.setOptClose(dailyDataService.getDailyClose(stockName, date));
            if (operation.equals(OperationConstant.MOCK_BUY)
                    || operation.equals(OperationConstant.MOCK_SELL)) {
                stockOperateDTO.setPrice(dailyDataService.getDailyClose(stockName, date));
            }

            MonthDetail currentMonthDetail = monthDataService.getCurrentMonthDetail(stockName);
            Double basePrice = stockOperateDTO.getPrice();
            // 与当前价格的差距
            stockOperateDTO.setCurPct(
                    NumberUtil.calPct(currentMonthDetail.getClose(), basePrice)
            );
            if (stockOperateDTO.getOptClose() != null) {
                stockOperateDTO.setOptCurPct(
                        NumberUtil.calPct(currentMonthDetail.getClose(), stockOperateDTO.getOptClose())
                );
            }

            List<DailyDetailDTO> list = dailyDataService.getDailyData(stockName)
                    .stream()
                    .filter(item -> item.getDate().compareTo(date) >= 0).limit(10).toList();


            if (list.isEmpty() || !list.getFirst().getDate().equals(date)) {
                return;
            }

            DailyDetail optDayItem = list.getFirst();

            stockOperateDTO.setOptClose(optDayItem.getClose());
            stockOperateDTO.setPct(optDayItem.getPct());
            stockOperateDTO.setLevelPoint(optDayItem.getLp());
            stockOperateDTO.setDrawdown(optDayItem.getDrawdown());

            if (list.size() > 1) {

                DailyDetail min = list.stream().min(Comparator.comparing(DailyDetail::getClose)).get();
                DailyDetail max = list.stream().max(Comparator.comparing(DailyDetail::getClose)).get();

                // 近10个交易日最小值
                stockOperateDTO.setD10MinDate(min.getDate());
                stockOperateDTO.setD10MinClose(min.getClose());
                stockOperateDTO.setD10MinPct(
                        NumberUtil.calPct(min.getClose(), basePrice)
                );
                stockOperateDTO.setOptD10MinPct(
                        NumberUtil.calPct(min.getClose(), stockOperateDTO.getOptClose())
                );

                // 近10个交易日最大值
                stockOperateDTO.setD10MaxDate(max.getDate());
                stockOperateDTO.setD10MaxClose(max.getClose());
                stockOperateDTO.setD10MaxPct(
                        NumberUtil.calPct(max.getClose(), basePrice)
                );
                stockOperateDTO.setOptD10MaxPct(
                        NumberUtil.calPct(max.getClose(), stockOperateDTO.getOptClose())
                );
            }
        });

        return ret;
    }
}
